package huanzhao.erp.service;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import huanzhao.erp.domain.entity.Clear;
import huanzhao.erp.domain.entity.ClearRecord;
import huanzhao.erp.domain.entity.Comment;
import huanzhao.erp.domain.po.Result;
import huanzhao.erp.domain.types.CommentType;
import huanzhao.erp.domain.vo.ClearRecordVO;
import huanzhao.erp.domain.vo.ClearVO;
import huanzhao.erp.mapper.ClearMapper;
import huanzhao.erp.mapper.ClearRecordMapper;
import huanzhao.erp.mapper.CommentMapper;
import huanzhao.erp.mapper.PhoneMapper;
import org.hibernate.validator.constraints.Range;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

import javax.validation.constraints.NotBlank;
import java.util.*;

/**
 * @author April
 * 2024/10/10 11:49
 * @version 1.0
 */
@Service
public class ClearService extends ServiceImpl<ClearMapper, Clear> {
    private final ClearMapper clearMapper;
    private final ClearRecordMapper clearRecordMapper;
    private final ConvertService convertService;
    private final PhoneMapper phoneMapper;
    private final CommentMapper commentMapper;

    public ClearService(ClearMapper clearMapper, ClearRecordMapper clearRecordMapper, ConvertService convertService, PhoneMapper phoneMapper, CommentMapper commentMapper) {
        this.clearMapper = clearMapper;
        this.clearRecordMapper = clearRecordMapper;
        this.convertService = convertService;
        this.phoneMapper = phoneMapper;
        this.commentMapper = commentMapper;
    }

    /**
     * 检查当前系统是否为大盘库状态
     *
     * @return boolean
     * 2024/10/10 11:52:35
     */
    public boolean isInBigClear() {
        return clearMapper.isInBigClear();
    }

    /**
     * 查询盘库列表
     *
     * @param state 盘库的状态：0->所有盘库记录，1->正在进行的盘库，2->历史盘库记录
     * @return 2024/10/12 19:29:39
     */
    public IPage<ClearVO> getClearList(@Range(max = 2) int state, int pageNum, int pageSize) {
        IPage<Clear> page = switch (state) {
            case 0 -> clearMapper.selectPage(Page.of(pageNum, pageSize), null);
            case 1 -> clearMapper.getRunningClears(Page.of(pageNum, pageSize));
            case 2 -> clearMapper.getFinishedClears(Page.of(pageNum, pageSize));
            default -> new Page<>();
        };

        List<ClearVO> result = new ArrayList<>();
        page.getRecords().forEach(clear -> result.add(convertService.convertClear(clear)));
        return new Page<ClearVO>().setRecords(result).setTotal(page.getTotal());
    }

    /**
     * 启动盘库
     *
     * @param big      是否为大盘库
     * @param imeiList 为小盘库时可用，本次盘库的手机imei列表
     * @param comment  备注，为小盘库可用
     * @return Result<?>
     * 2024/10/12 20:30:49
     */
    @Transactional(isolation = Isolation.READ_COMMITTED)
    public Result<?> startClear(boolean big, List<String> imeiList, String comment) {
        Set<Long> phoneIds = new HashSet<>();
        List<String> notFoundImeiLists = new ArrayList<>();
        if (big) {
            if (isInBigClear()) {
                return Result.error("已有大盘库在进行中，请勿重复启动！");
            }
            // 大盘库，获取系统中所有符合条件的手机id
            List<Long> ids = phoneMapper.getAllInSystemPhoneIds(null);
            if (ids != null) {
                phoneIds.addAll(ids);
            }
        } else {
            if (imeiList == null) {
                return Result.error("手机imei列表不能为空");
            }
            // 小盘库
            for (String imei : imeiList) {
                List<Long> ids = phoneMapper.getAllInSystemPhoneIds(imei);
                if (ids == null) {
                    notFoundImeiLists.add(imei);
                } else {
                    phoneIds.addAll(ids);
                }
            }
            // 添加盘库备注
            phoneIds.forEach(phoneId -> commentMapper.insert(new Comment(phoneId, CommentType.CLEAR, comment)));
        }
        if (phoneIds.isEmpty()) {
            return Result.error("系统中没有符合条件的手机，启动盘库失败！", notFoundImeiLists);
        }
        // 启动盘库
        Clear clear = new Clear(big);
        clearMapper.insert(clear);

        // 添加相应的盘库记录
        phoneIds.forEach(phoneId -> clearRecordMapper.insert(new ClearRecord(clear.getId(), phoneId)));
        return Result.ok("启动盘库成功，本次共盘库" + phoneIds.size() + "台手机", notFoundImeiLists);
    }

    /**
     * 盘点确认
     *
     * @return Result<?>
     * 2024/10/13 09:12:52
     */
    @Transactional(isolation = Isolation.READ_COMMITTED)
    public Result<?> confirmClear(@NotBlank String imei, long clearId) {
        Clear clear = clearMapper.selectById(clearId);
        if (clear == null) {
            return Result.error("盘库记录不存在");
        }
        if (clear.getFinishTime() != null) {
            return Result.error("盘库已结束");
        }
        List<Long> phoneIds = phoneMapper.getAllInSystemPhoneIds(imei);
        if (phoneIds == null) {
            return Result.error("系统中没有该手机");
        }
        // 同一个imei可能匹配多个手机，检查是否有多个手机在盘库中
        Set<Long> inClearPhoneIds = new HashSet<>();
        for (Long phoneId : phoneIds) {
            if (clearRecordMapper.isPhoneInClear(clearId, phoneId)) {
                inClearPhoneIds.add(phoneId);
            }
        }
        if (inClearPhoneIds.isEmpty()) {
            return Result.error("该手机不在盘库中");
        }
        // 若多个手机都在盘库中，也依次对其进行确认（目前的做法，后面可能会改）
        inClearPhoneIds.forEach(phoneId -> clearRecordMapper.confirmClear(clearId, phoneId, true));
        return Result.ok("确认盘点成功，本次共确认" + inClearPhoneIds.size() + "台手机");
    }

    /**
     * 结束盘库
     *
     * @return Result<?>
     * 2024/10/13 09:29:00
     */
    @Transactional(isolation = Isolation.READ_COMMITTED)
    public Result<?> finishClear(long clearId) {
        Clear clear = clearMapper.selectById(clearId);
        if (clear == null) {
            return Result.error("盘库记录不存在");
        }
        if (clear.getFinishTime() != null) {
            return Result.error("盘库已结束");
        }
        // 将盘库中未确认的手机标记为未找到
        clearRecordMapper.confirmClear(clearId, null, false);
        // 结束盘库
        clearMapper.finishClear(clearId);
        return Result.ok("结束盘库成功");
    }

    /**
     * 查询特定盘库记录中的手机
     *
     * @param found 手机是否已找到
     * @return 返回手机id数组
     * 2024/10/13 09:51:54
     */
    public Result<List<Long>> getClearPhones(long clearId, Boolean found) {
        Clear clear = clearMapper.selectById(clearId);
        if (clear == null) {
            return Result.error("盘库记录不存在");
        }
        if (clear.getFinishTime() != null) {
            return Result.error("盘库已结束");
        }
        List<Long> clearPhones = clearRecordMapper.getClearPhones(clearId, found);
        return Result.ok(Objects.requireNonNullElse(clearPhones, Collections.emptyList()));
    }

    /**
     * 查询特定盘库记录
     *
     * @return Result<ClearVO>
     * 2024/10/13 09:56:00
     */
    public Result<ClearVO> getClearById(long clearId) {
        Clear clear = clearMapper.selectById(clearId);
        if (clear == null) {
            return Result.error("盘库记录不存在");
        }
        return Result.ok(convertService.convertClear(clear));
    }

    /**
     * 查询手机的盘库记录
     * @return Result<List<ClearRecordVO>>
     * 2024/10/13 09:56:33
     */
    public Result<List<ClearRecordVO>> getPhoneClearRecords(@NotBlank String imei) {
        List<Long> phoneIds = phoneMapper.getIdByImei(imei);
        if (phoneIds == null) {
            return Result.error("系统中没有该手机");
        }
        List<ClearRecordVO> result = new ArrayList<>();
        phoneIds.forEach(phoneId -> {
            List<ClearRecord> clearRecords = clearRecordMapper.selectByPhoneId(phoneId);
            if (clearRecords != null) {
                clearRecords.forEach(clearRecord -> result.add(convertService.convertClearRecord(clearRecord)));
            }
        });
        return Result.ok(result);
    }
}
